﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Xml;
using System.IO;

namespace StatsGraphs
{
    [ScriptableType]
    public partial class Page : UserControl
    {
        /// <summary>
        /// Event that alert when a graphic is refreshed
        /// </summary>
        [ScriptableMember]
        public event EventHandler OnGraphRefresh;

       
       private string subject;
       /// <summary>
       /// The subject of the graph. It is a property updateable outside this module via javascript
       /// </summary>
        [ScriptableMember]
        public string Subject {
            get
            {
                return subject;
            }
            set
            {
                subject = value;
                typeGraphRequest();
            } 
        }

        
        private int month;
        /// <summary>
        ///  The month related to the dates shown into the graph. It is a property updateable outside this module via javascript    
        /// </summary>
        [ScriptableMember]
        public int Month
        {
            get
            {
                return month;
            }
            set
            {
                month = value;
                typeGraphRequest();
            }
        }

        
        private int year;
        ///<summary>
        /// The year related to the dates shown into the graph. It is a property updateable outside this module via javascript
        /// </summary>  
        [ScriptableMember]
        public int Year
        {
            get
            {
                return year;
            }
            set
            {
                year = value;
                typeGraphRequest();
            }
        }

        
        private string language;
        ///<summary>
        /// The language used in the graph's labels. It is a property updateable outside this module via javascript
        /// </summary>
        [ScriptableMember]
        public string UserLanguage
        {
            get
            {
                return language;
            }
            set
            {
                language = value;
            }
        }

        ///<value>
        /// Web Service reference
        /// </value>
        private WSStatsReference.WSStatsClient proxy; 

        /// <summary>
        /// Initialize the page setting the WebService and the basic variables needed in the creation of the control
        /// </summary>
        public Page()
        {
            InitializeComponent();

            this.Loaded += new RoutedEventHandler(Page_Loaded);
            
            //Connection to the WS
            BasicHttpBinding binding = new BasicHttpBinding();

            EndpointAddress address = new EndpointAddress("http://triploa.cli.di.unipi.it/service/wcf/WSStats.svc");


            //Line for local WS connection: useful in future tests
            //EndpointAddress address = new EndpointAddress("http://localhost:2588/WSStats.svc");

            proxy = new WSStatsReference.WSStatsClient(binding, address);

            //Default values
            year = DateTime.Now.Year;
            month = 0;
            language = "it-IT"; 
            subject = "savedPollution";
            typeGraphRequest();
        }

        /// <summary>
        /// This method invokes the services offered by the WS
        /// </summary>
        private void typeGraphRequest()
        {
            if (month <= 0 || month > 12) // Year Stats required
            {
                proxy.GetYearStatsCompleted += new EventHandler<WSStatsReference.GetYearStatsCompletedEventArgs>(createYearChart);
                proxy.GetYearStatsAsync(subject, year);

            }
            else // Month Stats required
            {

                proxy.GetMonthStatsCompleted += new EventHandler<WSStatsReference.GetMonthStatsCompletedEventArgs>(createMonthChart);
                proxy.GetMonthStatsAsync(subject, year, month);

            }
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
 
        }


        /// <summary>
        /// This methods provides data for the year Chart Table. It is called when a getYearStats event is raised
        /// </summary>
        /// <param name="sender">The event sender</param>
        /// <param name="e">The event</param>
        public void createYearChart(object sender, StatsGraphs.WSStatsReference.GetYearStatsCompletedEventArgs e)
        {

            Visifire.Charts.DataSeries dataSeries = new Visifire.Charts.DataSeries();

            //settings for a better reading of the xml document by the xmlReader    
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            settings.IgnoreComments = true;
            settings.IgnoreWhitespace = true;

            XmlReader reader;
            //end of settings

            //creating a compatible with silverlight XmlReader
            try
            {
                reader = XmlReader.Create("language." + language + ".xml", settings); //open the language file
            }
            catch (FileNotFoundException)
            {
                reader = XmlReader.Create("language.en-GB.xml", settings); //open the english language file in case the requested is not found
            }

            String Attribute = "";
            int monthIter = 0;
            string[] monthLabels = new string[12];//the array of month names
            List<InterStrings> graphStr = new List<InterStrings>();//a list of subject

            while (reader.Read())
            {
                Attribute = reader.GetAttribute("type");
               
                //read the whole language XML file and store in memory the names: months are saved in an array, subjects in a list. this choice is
                //because we decide to give the chance to add more subjects only to the XML file.
                if (Attribute == "month")
                {
                    monthLabels[monthIter] = reader.GetAttribute("value");//array of months
                    monthIter++;
                }
                if (Attribute == "subject")
                {
                    graphStr.Add(new InterStrings(reader.GetAttribute("name"), reader.GetAttribute("value")));//list of subject
                }
            }
            
            
            for (int i = 0; i < 11; i++ )
            {
                Visifire.Charts.DataPoint dataPoint = new Visifire.Charts.DataPoint();
                dataPoint.AxisLabel = monthLabels[i];
                dataPoint.YValue = (double)(e.Result.monthlyData[i]);
                dataSeries.Children.Add(dataPoint);
            }

            
            string graphTitle = "Silverlight graph control";//default title
            
            //check the list of subject looking for the desired graph title
            for (int listIter = 0; listIter < graphStr.Count; listIter++)
            {
                if (graphStr.ElementAt(listIter).name == subject) graphTitle = graphStr.ElementAt(listIter).value + " " + year;
            }
            

            CreateChart(dataSeries, graphTitle, "Column");
        }

        /// <summary>
        /// This methods provides data for the month Chart Table. It is called when a getMonthStats event is raised
        /// </summary>
        /// <param name="sender">The event sender</param>
        /// <param name="e">The event</param>
        public void createMonthChart(object sender, StatsGraphs.WSStatsReference.GetMonthStatsCompletedEventArgs e)
        {

            Visifire.Charts.DataSeries dataSeries = new Visifire.Charts.DataSeries();

            for (int i = 0; i < e.Result.daysData.Count(); i++)
            {
                Visifire.Charts.DataPoint dataPoint = new Visifire.Charts.DataPoint();
                dataPoint.AxisLabel = "" + (i + 1);
                dataPoint.YValue = (double)(e.Result.daysData[i]);
                dataSeries.Children.Add(dataPoint);
            }

            string graphTitle = "Silverlight graph control";

            //settings for a better reading of the xml document
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            settings.IgnoreComments = true;
            settings.IgnoreWhitespace = true;
            XmlReader reader;
            //end of settings

            //creating a compatible with silverlight XmlReader
            try
            {
                reader = XmlReader.Create("language." + language + ".xml", settings); //open the right language file
            }
            catch (FileNotFoundException)
            {
                reader = XmlReader.Create("language.en-GB.xml", settings); //open the english language file in case the requested is not found
            }
            
            String Attribute = "";
            List<InterStrings> graphStr = new List<InterStrings>();

            while(reader.Read())
            {
                Attribute = reader.GetAttribute("type");

                if(Attribute == "subject")
                { 
                    graphStr.Add(new InterStrings(reader.GetAttribute("name"), reader.GetAttribute("value")));
                }
            }

            for(int listIter = 0; listIter<graphStr.Count; listIter++)
            {
                if(graphStr.ElementAt(listIter).name == Subject) graphTitle = graphStr.ElementAt(listIter).value + " " + month + " / " + year;
            }



            CreateChart(dataSeries, graphTitle, "Line");
        }


        /// <summary>
        /// Create a Visifire chart with the given data.
        /// </summary>
        /// <param name="dataSeries">The data to build the chart with.</param>
        /// <param name="titleText">The title of the chart.</param>
        /// <param name="chartType">The type of the chart.</param>
        public void CreateChart(Visifire.Charts.DataSeries dataSeries, string titleText, string chartType)
        {
            Visifire.Charts.Chart visiChart = new Visifire.Charts.Chart();
            Visifire.Charts.Title title = new Visifire.Charts.Title();
            title.Text = titleText;
            visiChart.Children.Add(title);

            visiChart.Width = 450; // Width and Height are required for the Chart.
            visiChart.Height = 300;

            Random rand = new Random(DateTime.Now.Millisecond);
            
            dataSeries.RenderAs = chartType;
            visiChart.AnimationType = "Type5";
            visiChart.Children.Add(dataSeries);

            LayoutRoot.Children.Clear(); // So that Chart objects don’t build up each time we add one.
            LayoutRoot.Children.Add(visiChart);

            OnGraphRefresh(this, new StupidScriptableEventArg());
        }
    }

    [ScriptableType]
    public class StupidScriptableEventArg : EventArgs
    {
    }
}
